#include "consoleWidget.h"
#include "consoleWidget.moc"

using namespace std;

Console::Console (QWidget * parent) : QDockWidget(parent), hIdx(0), maxHist(100)
{
	///////////////////////////////////////
	//         Config Qt Widget          //
	///////////////////////////////////////
	this->setFloating(true);
    this->setFeatures(QDockWidget::DockWidgetFloatable);
	this->setAllowedAreas(Qt::BottomDockWidgetArea);

	QWidget* hookWidget = new QWidget();

	vertBox = new QVBoxLayout(this);

    textBox = new QTextEdit(this);
	textBox->setMinimumSize(400,200);
	textBox->setReadOnly(true);
	//textBox->move(this->width() - 400,this->height() - 100);


	luaPrompt = new QLineEdit(this);


    vertBox->addWidget(textBox);
    vertBox->addWidget(luaPrompt);

	hookWidget->setLayout(vertBox);

	this->setWidget(hookWidget);
	this->hide();

	connect(luaPrompt , SIGNAL( returnPressed() ),
			this, SLOT( interpretLua() ) );
}

void Console::init ( void )
{
	///////////////////////////////////////
	//          Config Lua               //
	///////////////////////////////////////
	L=lua_open();
	luaL_openlibs ( L );
	//wrap c++ functions
	//Console_Init(L);
	//Baijiaccessor_Init(L);
	//Meshmanager_Init(L);

	luaopen_console(L);
	luaopen_baijiAccessor(L);
	luaopen_meshManager(L);
	luaopen_mesh(L);

std::ifstream hist("console.hist");
	if(! hist.fail())
	{
		while(hist.good())
		{
			std::string command ;
			//FIXME: '\n' delimitor certainly won't work on win32
			getline(hist, command, '\n');
			historic.push_back(command);
		}
	}
	hist.close();
	std::ifstream init("console.init");
	if(!init.fail())
	{
		while(init.good())
		{
			std::string command ;
			//FIXME: '\n' delimitor certainly won't work on win32
			getline(init, command, '\n');
            cout << "init : " << command << endl;
            luaL_dostring(L, command.c_str());
        }
    }
	init.close();
}


void Console::print(char* txt)
{
	cout << "print on console : " << txt << endl;
	textBox->append(QString(txt));
}


void Console::keyPressEvent(QKeyEvent *e)
{

	if ((e->key()==Qt::Key_Up))
	{
		if(historic.size())
			luaPrompt->setText(historic[--hIdx%historic.size()].c_str());
	}
	else if ((e->key()==Qt::Key_Down))
	{
		if(historic.size())
			luaPrompt->setText(historic[++hIdx%historic.size()].c_str());
	}
	else
	{
		QDockWidget::keyPressEvent(e);
	}

}


void Console::interpretLua()
{
	string command = luaPrompt->text().toStdString();
	//this->gcn::TextBox::keyPressed(keyEvent);

	cout << "get lua command : " << command << endl;

	textBox->append(QString("# ") + luaPrompt->text());

    if(luaL_dostring(L, command.c_str()))
	{
		textBox->append(QString(lua_tostring(L,-1)));
	}

	luaPrompt->clear();

	if(command.size())
		historic.push_back(command);

	if(QGLViewer* viewer = dynamic_cast<QGLViewer*>(this->parent()))
	{
		viewer->updateGL();
	}
}

Console::~Console()
{
	lua_close ( L );
	std::ofstream hist("console.hist");

	unsigned int count = 0;
	for(std::vector<std::string>::iterator hIt = historic.begin() ; hIt != historic.end() ; hIt++)
	{
		hist << *hIt << std::endl;
		if(count++ >= maxHist)
			break;
	}
	hist.close();
}


